<template>
  <div class="p-6 max-w-5xl mx-auto">
    <h1 class="text-2xl font-bold mb-4">管理员数据查看</h1>

    <div class="mb-4 space-y-2">
      <label class="block">管理员密钥（只在本地保存于浏览器）</label>
      <div class="flex gap-2">
        <input v-model="adminKeyInput" type="password" class="border px-2 py-1 flex-1" placeholder="输入管理员密钥" />
        <button @click="saveKey" class="bg-blue-600 text-white px-3 py-1 rounded">保存并登录</button>
        <button @click="clearKey" class="bg-gray-200 px-3 py-1 rounded">登出</button>
      </div>
      <div v-if="!isAuthenticated" class="text-sm text-red-600">未认证。请输入有效密钥并保存。</div>
    </div>

    <div v-if="isAuthenticated">
      <div class="flex items-center gap-3 mb-4">
        <label>表：</label>
        <select v-model="table" @change="resetAndLoad" class="border px-2 py-1">
          <option value="lin_log">lin_log</option>
          <option value="lin_order">lin_order</option>
          <option value="lin_payinfo">lin_payinfo</option>
        </select>
        <input v-model="search" @keyup.enter="resetAndLoad" placeholder="搜索..." class="border px-2 py-1 flex-1" />
        <label class="text-sm">开始</label>
        <input type="datetime-local" v-model="startLocal" @change="resetAndLoad" class="border px-2 py-1" />
        <label class="text-sm">结束</label>
        <input type="datetime-local" v-model="endLocal" @change="resetAndLoad" class="border px-2 py-1" />
        <select v-model.number="pageSize" @change="resetAndLoad" class="border px-2 py-1">
          <option :value="10">10</option>
          <option :value="20">20</option>
          <option :value="50">50</option>
        </select>

        <button @click="resetAndLoad" class="bg-green-600 text-white px-3 py-1 rounded">刷新</button>
      </div>

      <div v-if="loading" class="py-6 text-center">加载中...</div>
      <div v-if="error" class="text-red-600">{{ error }}</div>

      <div v-if="rows.length === 0 && !loading" class="text-gray-500">无数据</div>

      <div v-if="rows.length">
        <div class="overflow-auto border rounded">
          <table class="min-w-full table-auto text-sm">
            <thead class="bg-gray-100">
              <tr>
                <th v-if="table === 'lin_order'" class="px-3 py-2 text-left">操作</th>
                <th v-for="col in columns" :key="col" class="px-3 py-2 text-left">{{ col }}</th>
              </tr>
            </thead>
            <tbody>
              <tr v-for="(r, idx) in rows" :key="idx" class="odd:bg-white even:bg-gray-50 align-top">
                <td v-if="table === 'lin_order'" class="px-3 py-2 align-top">
                  <div class="flex items-center gap-2">
                    <button
                      v-if="isUnpaid(r)"
                      :disabled="fixing[r.id]"
                      @click="fixOrder(r)"
                      class="bg-yellow-500 text-white px-2 py-1 rounded text-sm"
                    >
                      {{ fixing[r.id] ? '处理中...' : '修复并标为已支付' }}
                    </button>
                    <span v-else class="text-sm text-gray-500">不需要修复</span>
                  </div>
                </td>
                <td v-for="col in columns" :key="col" class="px-3 py-2 align-top">
                  <pre class="whitespace-pre-wrap">{{ formatCell(r[col]) }}</pre>
                </td>
              </tr>
            </tbody>
          </table>
        </div>

        <div class="flex items-center justify-between mt-3">
          <div>第 {{ page }} 页 / 共 {{ totalPages }} 页， 共 {{ total }} 条</div>
          <div class="flex items-center gap-2">
            <button :disabled="page<=1" @click="goto(page-1)" class="px-2 py-1 border rounded">上一页</button>
            <input type="number" v-model.number="gotoPage" class="w-20 px-2 py-1 border" />
            <button @click="goto(gotoPage)" class="px-2 py-1 border rounded">跳转</button>
            <button :disabled="page>=totalPages" @click="goto(page+1)" class="px-2 py-1 border rounded">下一页</button>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
definePageMeta({ middleware: 'admin-access' })
import { ref, computed, watch, onMounted } from 'vue'

// Avoid accessing localStorage during SSR. Initialize empty and hydrate onMounted.
const adminKeyInput = ref('')
const adminKey = ref('')
const isAuthenticated = computed(() => !!adminKey.value)

const table = ref('lin_log')
const rows = ref([])
const columns = ref([])
const page = ref(1)
const pageSize = ref(20)
const total = ref(0)
const loading = ref(false)
const error = ref('')
const search = ref('')
const gotoPage = ref(1)
const startLocal = ref('')
const endLocal = ref('')
const fixing = ref({})

function saveKey() {
  adminKey.value = adminKeyInput.value
  if (adminKey.value) localStorage.setItem('admin_key', adminKey.value)
  resetAndLoad()
}

function clearKey() {
  adminKeyInput.value = ''
  adminKey.value = ''
  localStorage.removeItem('admin_key')
}

function formatCell(v) {
  if (v === null || v === undefined) return ''
  if (typeof v === 'object') return JSON.stringify(v)
  return String(v)
}

const totalPages = computed(() => Math.max(1, Math.ceil(total.value / pageSize.value)))

async function load() {
  if (!adminKey.value) return
  loading.value = true
  error.value = ''
  try {
    const path = `/api/admin/${table.value}`
  const params = { page: page.value, pageSize: pageSize.value, search: search.value }
  if (startLocal.value) params.start = formatForServer(startLocal.value)
  if (endLocal.value) params.end = formatForServer(endLocal.value)
    const res = await $fetch(path, { method: 'GET', headers: { 'x-admin-key': adminKey.value }, params })
    if (res && res.data) {
      rows.value = res.data || []
      total.value = res.total || 0
      columns.value = rows.value.length ? Object.keys(rows.value[0]) : []
      gotoPage.value = page.value
    } else if (res && res.status === 401) {
      error.value = '未授权：密钥无效'
    } else if (res && res.status === 500) {
      error.value = res.message || '服务器错误'
    }
  } catch (err) {
    error.value = String(err?.message || err)
  } finally {
    loading.value = false
  }
}

function formatForServer(localValue) {
  // localValue expected like '2025-11-05T09:21' or '2025-11-05T09:21:34'
  if (!localValue) return ''
  // replace 'T' with space
  let s = String(localValue).replace('T', ' ')
  // ensure seconds
  if (s.length === 16) s = s + ':00'
  return s
}

function resetAndLoad() {
  page.value = 1
  load()
}

function isUnpaid(r) {
  if (!r) return false
  const s = r.status
  // 归一化为字符串再判断，包含英文与常见中文表示
  const val = s === null || s === undefined ? '' : String(s).trim()
  return ['unpaid', 'pending', 'created', '0', '', '未支付', '待支付', '未付款'].includes(val)
}

async function fixOrder(r) {
  if (!r || !r.id) return
  if (!confirm(`确定将订单 ${r.id} 标记为已支付并同步 product_info 吗？`)) return
  try {
    fixing.value[r.id] = true
  const res = await $fetch('/api/admin/lin_order.fix', {
      method: 'POST',
      headers: { 'x-admin-key': adminKey.value },
      body: { id: r.id }
    })
    if (res && res.status === 200) {
      const updated = res.data
      if (updated) {
        // 更新当前行数据
        Object.keys(updated).forEach(k => { r[k] = updated[k] })
      }
      alert('订单已更新')
    } else {
      alert('更新失败: ' + (res?.message || res?.status || 'unknown'))
    }
  } catch (e) {
    alert('请求出错: ' + String(e?.message || e))
  } finally {
    fixing.value[r.id] = false
  }
}

function goto(p) {
  const pn = Number(p) || 1
  page.value = Math.min(Math.max(1, pn), totalPages.value)
  load()
}

watch([table, pageSize], () => { resetAndLoad() })

// hydrate from localStorage and trigger initial load on client only
onMounted(() => {
  try {
    const saved = typeof window !== 'undefined' ? localStorage.getItem('admin_key') : null
    if (saved) {
      adminKeyInput.value = saved
      adminKey.value = saved
      resetAndLoad()
    }
  } catch (e) {
    // ignore localStorage errors
  }
})
</script>

<style scoped>
pre { margin: 0; font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, 'Roboto Mono', 'Liberation Mono', monospace; font-size: 12px }
</style>
